//
// Created by youle on 20-5-20.
//

#ifndef CXX11_SPIN_MUTEX_H
#define CXX11_SPIN_MUTEX_H

#include <atomic>
#include <thread>
#include <mutex>
#include <iostream>

/*
 通过指定内存序代替默认的std::memory_order_seq_cst可以提高性能。C++11的std::memory_order有6个枚举值。
Value 	                  |  描述
--------------------------------------------------------------------------------
std::memory_order_relaxed |	没有任何同步和排序限制，只需保证操作是原子的。
--------------------------------------------------------------------------------
std::memory_order_consume |	一个指定了此值的load操作在受影响的内存位置上执行consume操作，
                            此操作使得另一个在同一内存位置执行了release操作的线程在此之前对数据依赖(data-dependent)的内存位置的写操作为当前线程可见。
--------------------------------------------------------------------------------
std::memory_order_acquire |	一个指定了此值的load操作在受影响的内存位置上执行acquire操作，
                            此操作使得另一个在同一内存位置执行了release操作的线程在此之前对任意的内存位置的写操作为当前线程可见。
--------------------------------------------------------------------------------
std::memory_order_release |	一个指定了此值的store操作在受影响的内存位置上执行release操作，
                            此操作使得此线程之前对数据依赖(data-dependent)的内存位置的写操作为另一个在此之后通过对同一内存位置执行consume操作的线程可见，使得此线程之前对任意的内存位置的写操作为另一个在此之后通过对同一个内存位置执行acquire操作的线程可见。
--------------------------------------------------------------------------------
std::memory_order_acq_rel |	一个指定了此值的read-modify-write操作，在读阶段(相当于load)对受影响的内存位置执行acquire操作，
                            在写阶段(相当于store)对同一内存位置执行release操作。
--------------------------------------------------------------------------------
std::memory_order_seq_cst |	顺序一致性，所有的线程观察到的整个程序中内存修改顺序是一致的。
 */

class SpinMutex {
public:
    SpinMutex() = default;
    SpinMutex(const SpinMutex&) = delete;
    SpinMutex& operator= (const SpinMutex&) = delete;
    void lock() {
        while(flag.test_and_set(std::memory_order_acquire)){}
    }
    void unlock() {
        flag.clear(std::memory_order_release);
    }

private:
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
};


#endif //CXX11_SPIN_MUTEX_H

